/**
 *
 * 手写Promise
 */

const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class MyPromise{
  //状态
  PromiseState = PENDING
  //结果
  PromiseResult = null

  //保存两组回调函数
  fulfilledCbs = []
  rejectedCbs = []

  /**
   * 构造函数
   * @param executor 执行器
   */
  constructor(executor){
    try{
      executor(this.resolve, this.reject)
    }catch(e){
      this.reject(e)
    }
  }

  /**
   * 成功回调,设置成功状态和结果
   */
  resolve = (val) => {
    //状态只能改变一次
    if(this.PromiseState!== PENDING) return
    this.PromiseState = FULFILLED
    this.PromiseResult = val

    while (this.fulfilledCbs.length){
      this.fulfilledCbs.shift()()
    }
  }
  reject = (reason) => {
    //状态只能改变一次
    if(this.PromiseState !== PENDING) return
    this.PromiseState = REJECTED
    this.PromiseResult = reason

    while (this.rejectedCbs.length){
      this.rejectedCbs.shift()()
    }
  }

  /**
   * then方法接受成功和失败两个回调
   * then方法本身会返回一个新的Promise对象。
   * 该对象的状态和结果由回调函数的返回值决定
   * 如果返回值是promise对象，
   *    返回值为成功，新promise就是成功
   *    返回值为失败，新promise就是失败
   * 如果返回值不是promise对象
   *    新promise就是成功，它的值就是返回值
   *
   * @param onFulfilled
   * @param onReject
   */
  then(onFulfilled,onReject){
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val;
    onReject = typeof  onReject === 'function' ? onReject : reason => {throw reason}
    if (this.PromiseState === FULFILLED) {
      //成功回调
      onFulfilled(this.PromiseResult)

    }else if (this.PromiseState === REJECTED){
      //失败回调
      onReject(this.PromiseResult)

    }else if(this.PromiseState === PENDING){
      //待定状态
      this.fulfilledCbs.push(onFulfilled.bind(this,this.PromiseResult))
      this.rejectedCbs.push(onReject.bind(this,this.PromiseResult))
    }
  }

}
